package com.apkcore.core


import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.lifecycle.asLiveData
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch

object FlowBusX2 {
    private const val TAG = "FlowBusX"

    //    private val eventFlowMap = mutableMapOf<String, Channel<Any?>>()
    private val eventFlowMap = mutableMapOf<String, MutableSharedFlow<Any>>()

    /**
     *
     */
    fun <T> with(key: String, type: (Class<T>)? = null): EventSender<T> {
        @Suppress("UNCHECKED_CAST")
        val eventFlow =
            eventFlowMap.getOrPut(key) {
                MutableSharedFlow(
                    0,
                    1,
                    BufferOverflow.DROP_OLDEST
                )
            } as MutableSharedFlow<T>
//            eventFlowMap.getOrPut(key) { Channel(Channel.CONFLATED) } as Channel<T?>
        return EventSender(eventFlow)
    }

    class EventSender<T>(private val eventFlow: MutableSharedFlow<T>) {
        fun post(event: T) {
            Log.d(TAG, "post: $event")
////            // 当 MutableStateFlow 的值没有发生变化时，它不会发送新的值给正在收集的观察者。这是为了减少不必要的通知，提高性能。
////            // 但在这里就会出现订阅不发送的bug，所以可以先改变值为null，再去触发
//            eventFlow.value = null // 设置为 null 触发通知 MutableStateFlow 的一个特性。
//            eventFlow.value = event
            eventFlow.tryEmit(event)
        }

        suspend fun collect(lifecycleOwner: LifecycleOwner? = null, action: (T) -> Unit) {
//            eventFlow.consumeAsFlow().collect{event ->
            eventFlow.collect { event ->
                lifecycleOwner?.let {
                    it.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                        action(event)
                    }
                } ?: run {
                    action(event)
                }
            }
        }

        fun collect(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
            eventFlow.asLiveData().observe(lifecycleOwner, observer)
        }
    }
//    fun <T> EventSender<T>.launchIn(
//        scope: CoroutineScope,
//        lifecycleOwner: LifecycleOwner? = null,
//        action: (T) -> Unit
//    ): Job = scope.launch {
//        collect(lifecycleOwner, action)
//    }
}
